﻿using System;
using System.ComponentModel;
using System.Data.Linq;
using System.Data.Linq.Mapping;

namespace Angerona.Model
{

    [Table]
    public class VehiclesTable : INotifyPropertyChanged, INotifyPropertyChanging
    {

        [Column(IsVersion = true)]
        private Binary _version;

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region INotifyPropertyChanging Members
        public event PropertyChangingEventHandler PropertyChanging;

        private void NotifyPropertyChanging(string propertyName)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }
        #endregion

        //
        // Definizione delle colonne utilizzabili
        //

        private int _vId;
        [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
        public int VId
        {
            get { return _vId; }
            set
            {
                if (_vId != value)
                {
                    NotifyPropertyChanging("VId");
                    _vId = value;
                    NotifyPropertyChanged("VId");
                }
            }
        }

        //private Byte[] _imageOfCar;
        //[Column]
        //public Byte[] ImageOfCar
        //{
        //    get { return _imageOfCar; }
        //    set
        //    {
        //        if (_imageOfCar != null)
        //        {
        //            NotifyPropertyChanging("ImageOfCar");
        //            _imageOfCar = value;
        //            NotifyPropertyChanged("ImageOfCar");
        //        }
        //    }
        //}

        // TEST FOR ISOLATEDSTORAGE
        private string _imageOfCar;
        [Column]
        public string ImageOfCar
        {
            get { return _imageOfCar; }
            set
            {
                if (_imageOfCar != value)
                {
                    NotifyPropertyChanging("ImageOfCar");
                    _imageOfCar = value;
                    NotifyPropertyChanged("ImageOfCar");
                }
            }
        }

        private string _vehicleName;
        [Column]
        public string VehicleName
        {
            get { return _vehicleName; }
            set
            {
                if (_vehicleName != value)
                {
                    NotifyPropertyChanging("VehicleName");
                    _vehicleName = value;
                    NotifyPropertyChanged("VehicleName");
                }
            }
        }

        private string _manufacter;
        [Column]
        public string Manufacter
        {
            get { return _manufacter; }
            set
            {
                if (_manufacter != value)
                {
                    NotifyPropertyChanging("Manufacter");
                    _manufacter = value;
                    NotifyPropertyChanged("Manufacter");
                }
            }
        }

        private string _vehicleModel;
        [Column]
        public string VehicleModel
        {
            get { return _vehicleModel; }
            set
            {
                if (_vehicleModel != value)
                {
                    NotifyPropertyChanging("VehicleModel");
                    _vehicleModel = value;
                    NotifyPropertyChanged("VehicleModel");
                }
            }
        }

        private string _fuelType;
        [Column]
        public string FuelType
        {
            get { return _fuelType; }
            set
            {
                if (_fuelType != value)
                {
                    NotifyPropertyChanging("FuelType");
                    _fuelType = value;
                    NotifyPropertyChanged("FuelType");
                }
            }
        }

        private string _kwPower;
        [Column]
        public string KwPower
        {
            get { return _kwPower; }
            set
            {
                if (_kwPower != value)
                {
                    NotifyPropertyChanging("KwPower");
                    _kwPower = value;
                    NotifyPropertyChanged("KwPower");
                }
            }
        }

        private string _horsePower;
        [Column]
        public string HorsePower
        {
            get { return _horsePower; }
            set
            {
                if (_horsePower != value)
                {
                    NotifyPropertyChanging("HorsePower");
                    _horsePower = value;
                    NotifyPropertyChanged("HorsePower");
                }
            }
        }

        private string _engineCapacity;
        [Column]
        public string EngineCapacity
        {
            get { return _engineCapacity; }
            set
            {
                if (_engineCapacity != value)
                {
                    NotifyPropertyChanging("EngineCapacity");
                    _engineCapacity = value;
                    NotifyPropertyChanged("EngineCapacity");
                }
            }
        }

        private string _plateNumber;
        [Column]
        public string PlateNumber
        {
            get { return _plateNumber; }
            set
            {
                if (_plateNumber != value)
                {
                    NotifyPropertyChanging("PlateNumber");
                    _plateNumber = value;
                    NotifyPropertyChanged("PlateNumber");
                }
            }
        }

        private string _serialNumber;
        [Column]
        public string SerialNumber
        {
            get { return _serialNumber; }
            set
            {
                if (_serialNumber != value)
                {
                    NotifyPropertyChanging("SerialNumber");
                    _serialNumber = value;
                    NotifyPropertyChanged("SerialNumber");
                }
            }
        }

        private DateTime _productionDate;
        [Column]
        public DateTime ProductionDate
        {
            get { return _productionDate; }
            set
            {
                if (_productionDate != value)
                {
                    NotifyPropertyChanging("ProductionDate");
                    _productionDate = value;
                    NotifyPropertyChanged("ProductionDate");
                }
            }
        }

        private DateTime _purchasedDate;
        [Column]
        public DateTime PurchasedDate
        {
            get { return _purchasedDate; }
            set
            {
                if (_purchasedDate != value)
                {
                    NotifyPropertyChanging("PurchasedDate");
                    _purchasedDate = value;
                    NotifyPropertyChanged("PurchasedDate");
                }
            }
        }

        private string _purchasedKm;
        [Column]
        public string PurchasedKm
        {
            get { return _purchasedKm; }
            set
            {
                if (_purchasedKm != value)
                {
                    NotifyPropertyChanging("PurchasedKm");
                    _purchasedKm = value;
                    NotifyPropertyChanged("PurchasedKm");
                }
            }
        }

        private string _traveledKm;
        [Column]
        public string TraveledKm
        {
            get { return _traveledKm; }
            set
            {
                if (_traveledKm != value)
                {
                    NotifyPropertyChanging("TraveledKm");
                    _traveledKm = value;
                    NotifyPropertyChanged("TraveledKm");
                }
            }
        }

        private string _assuranceCompany;
        [Column]
        public string AssuranceCompany
        {
            get { return _assuranceCompany; }
            set
            {
                if (_assuranceCompany != value)
                {
                    NotifyPropertyChanging("AssuranceCompany");
                    _assuranceCompany = value;
                    NotifyPropertyChanged("AssuranceCompany");
                }
            }
        }

        private string _assuranceNumber;
        [Column]
        public string AssuranceNumber
        {
            get { return _assuranceNumber; }
            set
            {
                if (_assuranceNumber != value)
                {
                    NotifyPropertyChanging("AssuranceNumber");
                    _assuranceNumber = value;
                    NotifyPropertyChanged("AssuranceNumber");
                }
            }
        }

        private DateTime _assuranceDate;
        [Column]
        public DateTime AssuranceDate
        {
            get { return _assuranceDate; }
            set
            {
                if (_assuranceDate != value)
                {
                    NotifyPropertyChanging("AssuranceDate");
                    _assuranceDate = value;
                    NotifyPropertyChanged("AssuranceDate");
                }
            }
        }

        private DateTime _bollo;
        [Column]
        public DateTime Bollo
        {
            get { return _bollo; }
            set
            {
                if (_bollo != value)
                {
                    NotifyPropertyChanging("Bollo");
                    _bollo = value;
                    NotifyPropertyChanged("Bollo");
                }
            }
        }

        private DateTime _revision;
        [Column]
        public DateTime Revision
        {
            get { return _revision; }
            set
            {
                if (_revision != value)
                {
                    NotifyPropertyChanging("Revision");
                    _revision = value;
                    NotifyPropertyChanged("Revision");
                }
            }
        }

        //
        // Associazioni tra tabelle
        //

        private EntitySet<FuelData> _refueling = new EntitySet<FuelData>();
        [Association(Name = "namedRefueling", Storage = "_refueling", OtherKey = "_vehicleID", ThisKey = "VId")]
        public EntitySet<FuelData> Refueling
        {
            get { return _refueling; }
            set { _refueling = value; }
        }

        private EntitySet<GenericData> _genericEntitySet = new EntitySet<GenericData>();
        [Association(Name = "namedGeneric", Storage = "_genericEntitySet", OtherKey = "_vehicleID", ThisKey = "VId")]
        public EntitySet<GenericData> GenericEntitySet
        {
            get { return _genericEntitySet; }
            set { _genericEntitySet = value; }
        }

        // MaintenanceData
        private EntitySet<MaintenanceData> _maintenanceEntitySet = new EntitySet<MaintenanceData>();
        [Association(Name = "namedMaintenance", Storage = "_maintenanceEntitySet", OtherKey = "_vehicleID", ThisKey = "VId")]
        public EntitySet<MaintenanceData> MaintenanceEntitySet
        {
            get { return _maintenanceEntitySet; }
            set { _maintenanceEntitySet = value; }
        }


        // Assign handlers for the add and remove operations, respectively.
        public VehiclesTable()
        {
            _refueling = new EntitySet<FuelData>(
                new Action<FuelData>(this.attach_fuel),
                new Action<FuelData>(this.detach_fuel)
                );

            _genericEntitySet = new EntitySet<GenericData>(
                new Action<GenericData>(this.attach_generic),
                new Action<GenericData>(this.detach_generic)
                );

            _maintenanceEntitySet = new EntitySet<MaintenanceData>(
                new Action<MaintenanceData>(this.attach_maintenance),
                new Action<MaintenanceData>(this.detach_maintenance)
                );
        }

        // Called during an add operation
        private void attach_fuel(FuelData fuel)
        {
            NotifyPropertyChanging("FuelData");
            fuel.Vehicle = this;
        }

        private void attach_generic(GenericData generic)
        {
            NotifyPropertyChanging("GenericData");
            generic.Vehicle = this;
        }

        private void attach_maintenance(MaintenanceData maintenance)
        {
            NotifyPropertyChanging("MaintenanceData");
            maintenance.Vehicle = this;
        }

        // Called during a remove operation
        private void detach_fuel(FuelData fuel)
        {
            NotifyPropertyChanging("FuelData");
            fuel.Vehicle = null;
        }

        private void detach_generic(GenericData generic)
        {
            NotifyPropertyChanging("GenericData");
            generic.Vehicle = null;
        }

        private void detach_maintenance(MaintenanceData maintenance)
        {
            NotifyPropertyChanging("MaintenanceData");
            maintenance.Vehicle = null;
        }

    }

    //
    // Fuel Data
    //
    //
    [Table]
    public class FuelData : INotifyPropertyChanged, INotifyPropertyChanging
    {

        // Ottimizzazioni
        //
        [Column(IsVersion = true)]
        private Binary _version;

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region INotifyPropertyChanging Members
        public event PropertyChangingEventHandler PropertyChanging;

        private void NotifyPropertyChanging(string propertyName)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }
        #endregion

        private int _id;
        [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL IDENTITY")]
        public int Id
        {
            get { return _id; }
            set
            {
                NotifyPropertyChanging("Id");
                _id = value;
                NotifyPropertyChanged("Id");
            }
        }

        private float _spent;
        [Column]
        public float Spent
        {
            get { return _spent; }
            set
            {
                NotifyPropertyChanging("Spent");
                _spent = value;
                NotifyPropertyChanged("Spent");
            }
        }

        private float _quantity;
        [Column]
        public float Quantity
        {
            get { return _quantity; }
            set
            {
                NotifyPropertyChanging("Quantity");
                _quantity = value;
                NotifyPropertyChanged("Quantity");
            }
        }

        private DateTime _operationDate;
        [Column]
        public DateTime OperationDate
        {
            get { return _operationDate; }
            set
            {
                NotifyPropertyChanging("OperationDate");
                _operationDate = value;
                NotifyPropertyChanged("OperationDate");
            }
        }

        private string _operationNote;
        [Column]
        public string OperationNote
        {
            get { return _operationNote; }
            set
            {
                NotifyPropertyChanging("OperationNote");
                _operationNote = value;
                NotifyPropertyChanged("OperationNote");
            }
        }


        [Column]
        internal int _vehicleID;

        private EntityRef<VehiclesTable> _vehicleTable;
        [Association(Name = "namedRefueling", Storage = "_vehicleTable", ThisKey = "_vehicleID", OtherKey = "VId", IsForeignKey = true)]
        public VehiclesTable Vehicle
        {
            get { return _vehicleTable.Entity; }
            set
            {
                VehiclesTable previous = this._vehicleTable.Entity;
                if (previous != value || this._vehicleTable.HasLoadedOrAssignedValue == false)
                {
                    if (previous != null)
                    {
                        this._vehicleTable.Entity = null;
                        previous.Refueling.Remove(this);
                    }

                    this._vehicleTable.Entity = value;

                    if (value != null)
                    {
                        value.Refueling.Add(this);
                        // NOtificare il cambiamento
                        NotifyPropertyChanged("Vehicle");
                    }
                }
            }
        }

    }

    //
    // Generic Data
    //
    [Table]
    public class GenericData : INotifyPropertyChanged, INotifyPropertyChanging
    {
        [Column(IsVersion = true)]
        private Binary _version;

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region INotifyPropertyChanging Members
        public event PropertyChangingEventHandler PropertyChanging;

        private void NotifyPropertyChanging(string propertyName)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }
        #endregion

        private int _id;
        [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL IDENTITY")]
        public int Id
        {
            get { return _id; }
            set
            {
                NotifyPropertyChanging("Id");
                _id = value;
                NotifyPropertyChanged("Id");
            }
        }

        private DateTime _operationDate;
        [Column]
        public DateTime OperationDate
        {
            get { return _operationDate; }
            set
            {
                NotifyPropertyChanging("OperationDate");
                _operationDate = value;
                NotifyPropertyChanged("OperationDate");
            }
        }

        private string _operationNote;
        [Column]
        public string OperationNote
        {
            get { return _operationNote; }
            set
            {
                NotifyPropertyChanging("OperationNote");
                _operationNote = value;
                NotifyPropertyChanged("OperationNote");
            }
        }

        private float _spent;
        [Column]
        public float Spent
        {
            get { return _spent; }
            set
            {
                NotifyPropertyChanging("Spent");
                _spent = value;
                NotifyPropertyChanged("Spent");
            }
        }

        [Column]
        internal int _vehicleID;

        private EntityRef<VehiclesTable> _vehicleTable;
        [Association(Name = "namedGeneric", Storage = "_vehicleTable", ThisKey = "_vehicleID", OtherKey = "VId", IsForeignKey = true)]
        public VehiclesTable Vehicle
        {
            get { return _vehicleTable.Entity; }
            set
            {
                VehiclesTable previous = this._vehicleTable.Entity;
                if (previous != value || this._vehicleTable.HasLoadedOrAssignedValue == false)
                {
                    if (previous != null)
                    {
                        this._vehicleTable.Entity = null;
                        previous.GenericEntitySet.Remove(this);
                    }

                    this._vehicleTable.Entity = value;

                    if (value != null)
                    {
                        value.GenericEntitySet.Add(this);
                        // NOtificare il cambiamento
                        NotifyPropertyChanged("Vehicle");
                    }
                }
            }
        }

    }

    // 
    // Tabella Maintenance
    //
    [Table]
    public class MaintenanceData : INotifyPropertyChanged, INotifyPropertyChanging
    {
        [Column(IsVersion = true)]
        private Binary _version;

        #region INotifyPropertyChanged Members
        public event PropertyChangedEventHandler PropertyChanged;

        private void NotifyPropertyChanged(string propertyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        #region INotifyPropertyChanging Members
        public event PropertyChangingEventHandler PropertyChanging;

        private void NotifyPropertyChanging(string propertyName)
        {
            if (PropertyChanging != null)
            {
                PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
            }
        }
        #endregion

        private int _id;

        [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL IDENTITY")]
        public int Id
        {
            get { return _id; }
            set
            {
                NotifyPropertyChanging("Id");
                _id = value;
                NotifyPropertyChanged("Id");
            }
        }

        private float _spent;
        [Column]
        public float Spent
        {
            get { return _spent; }
            set
            {
                NotifyPropertyChanging("Spent");
                _spent = value;
                NotifyPropertyChanged("Spent");
            }
        }

        private DateTime _operationDate;
        [Column]
        public DateTime OperationDate
        {
            get { return _operationDate; }
            set
            {
                NotifyPropertyChanging("OperationDate");
                _operationDate = value;
                NotifyPropertyChanged("OperationDate");
            }
        }

        private string _operationNote;
        [Column]
        public string OperationNote
        {
            get { return _operationNote; }
            set
            {
                NotifyPropertyChanging("OperationNote");
                _operationNote = value;
                NotifyPropertyChanged("OperationNote");
            }
        }

        [Column]
        internal int _vehicleID;

        private EntityRef<VehiclesTable> _vehicleTable;
        [Association(Name = "namedMaintenance", Storage = "_vehicleTable", ThisKey = "_vehicleID", OtherKey = "VId", IsForeignKey = true)]
        public VehiclesTable Vehicle
        {
            get { return _vehicleTable.Entity; }
            set
            {
                VehiclesTable previous = this._vehicleTable.Entity;
                if (previous != value || this._vehicleTable.HasLoadedOrAssignedValue == false)
                {
                    if (previous != null)
                    {
                        this._vehicleTable.Entity = null;
                        previous.MaintenanceEntitySet.Remove(this);
                    }

                    this._vehicleTable.Entity = value;

                    if (value != null)
                    {
                        value.MaintenanceEntitySet.Add(this);
                        // NOtificare il cambiamento
                        NotifyPropertyChanged("Vehicle");
                    }
                }
            }

        }
    }

    //
    // LINQ TO SQL data context 
    //
    public class AngeronaDataContext : DataContext
    {
        // Passa la stringa di connessione alla classe base
        public AngeronaDataContext(string connectionString)
            : base(connectionString)
        { }

        // Specify a table for vehicles
        public Table<VehiclesTable> Vehicles;

        public Table<FuelData> Fuel;

        public Table<GenericData> Generic;

        public Table<MaintenanceData> Maintenance;

    }
}